#include <SPI.h>
#include <MFRC522.h>
#include "App_I2S.h"
#include "PIN.h"



MFRC522 mfrc522(SS_PIN, RST_PIN); 

MFRC522::MIFARE_Key key;           // 存放 Key A/B

void RC522_Init(void)
{
  SPI.begin(SCK_PIN, MISO_PIN, MOSI_PIN, SS_PIN);  // 初始化SPI总线
  mfrc522.PCD_Init();     // 初始化 RC522
  for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;  //先给key赋值
}




bool cardPresent = false;   //卡片是否存在的状态
int missCount = 0;         // 没有检测到卡片次数
const int missThreshold = 5; // 连续5次没检测到才算卡移走

//检测到卡片返回1，没有卡片返回0
bool RC522_Detect(void)
{
    if ( mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial() ) 
    {
        missCount = 0;  // 重置漏检计数
        if (!cardPresent) 
        {
            cardPresent = true;
            //播放语音，检测到卡片
            play_SD_video("/detected.wav");
        }
    } 
    else 
    {
        missCount++;
        if (missCount >= missThreshold && cardPresent) 
        {
            cardPresent = false;
            //播放语音，卡片被拿走
            play_SD_video("/removed.wav");
        }
    }

    return cardPresent;
}


//对要读写的区块进行认证
bool RC522_Authenticate(byte block_num)
{
    MFRC522::StatusCode status;

    status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block_num, &key, &(mfrc522.uid));
    if (status != MFRC522::STATUS_OK) 
    {
        Serial0.print("Authentication failed: ");
        Serial0.println(mfrc522.GetStatusCodeName(status));
        return false;
    }
    else
    {
        return true;
    }
}

// byte dataBlock[16] = { 'H','e','l','l','o',' ','W','o','r','l','d','!','0','1','2','3' };
//一次写入16字节
bool RC522_Writedata(byte block_num, byte *dataBlock, int dataBlock_len)
{
    MFRC522::StatusCode status;

    status = mfrc522.MIFARE_Write(block_num, dataBlock, dataBlock_len);
    if (status != MFRC522::STATUS_OK)
    {
        Serial0.print("Write failed: ");
        Serial0.println(mfrc522.GetStatusCodeName(status));
        return false;
    } 
    else 
    {
        Serial0.println("Write success!");
        return true;
    }
}
  
//读取时要求18字节，前16字节是内容，后2字节是CRC校验
bool RC522_Readdata(byte block_num, byte *dataBlock, byte *dataBlock_len)
{
    MFRC522::StatusCode status;

    status = mfrc522.MIFARE_Read(block_num, dataBlock, dataBlock_len);
    if (status != MFRC522::STATUS_OK) 
    {
        Serial0.print("Read failed: ");
        Serial0.println(mfrc522.GetStatusCodeName(status));
        return false;
    } 
    else 
    {
        Serial0.println("Read success!");
        return true;
    }
}


void RC522_quit(void)
{
    mfrc522.PICC_HaltA();
    mfrc522.PCD_StopCrypto1();
}



byte write_test[16] = {0};
byte write_len = 16;

byte read_test[18] = {0};
byte read_len = 18;
void RC522_test(void)
{
    if(RC522_Detect() == true) //检测成功
    {
        byte block_num = 6;
        byte test_num0 = 3;

        if(RC522_Authenticate(block_num) == true) //读写区块认证成功
        {
            // for(int i=0; i<16; i++)
            // {
            //     write_test[i] = test_num0;
            // }

            // for (byte i=0; i<16; i++) 
            // {
            //     Serial0.print(write_test[i]);
            //     Serial0.print(" ");
            // }
            // Serial0.print("\n");

            // RC522_Writedata(block_num, write_test, write_len);//写入数据
            // delay(100);

            RC522_Readdata(block_num, read_test, &read_len);
            for (byte i=0; i<16; i++) 
            {
                Serial0.print(read_test[i]);
                Serial0.print(" ");
            }
                Serial0.print("\n");
                Serial0.printf("%d\n",read_len);
        }
        RC522_quit();
    }
}

